/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package dipl.algorithm.math.utility;

import dipl.algorithm.math.fp.primitive.Point2df;
import dipl.algorithm.math.primitive.Point2d;
import dipl.algorithm.utility.convert.ApfloatConversion;
import java.util.Random;

/**
 * provides static methods for creating Point2d-sets
 */
public class Point2dSetFactory {

	/**
	 * parses given string containing control point coordinates.
	 * @param s
	 * @return curve or <code>null</code> if parsing failed
	 */
	protected static Point2d[] CreateFromString( String s ) {
		Point2df[] temp = dipl.algorithm.math.fp.utility.Point2dSetFactory.CreateFromString( s );
		if( temp == null )
			return null;
		return ApfloatConversion.ConvertPoints( temp );
	}

	/**
	 * Creates an array of random Point2d's using precision given by FPMath-object.
	 * param rand random number generator
	 * @param L number of bits maximally used in mantissa of resulting points, must be greater zero!
	 * param numPoints number of points to generate (must be greater 0!)
	 * @return point-array
	 */
	public static Point2d[] CreateRandom( Random rand, int numPoints ) {
		Point2d[] res = new Point2d[numPoints];
		for( int i = 0; i < res.length; i++ ) {
			res[i] = new Point2d(
				ApfloatUtils.ValueOf( -1.0+2.0*rand.nextDouble() ),
				ApfloatUtils.ValueOf( -1.0+2.0*rand.nextDouble() ) );
		}
		return res;
	}
	/**
	 * Creates an array of random Point2d's using precision given by FPMath-object
	 * and using maximally L-bits for storing the mantissa.
	 * In the paper of Yap the generated numbers are called (L,L)-bit floats.
	 * param rand random number generator
	 * @param L number of bits maximally used in mantissa of resulting points, must be greater zero!
	 * param numPoints number of points to generate (must be greater 0!)
	 * @return point-array
	 */
	public static Point2d[] CreateRandomLBit( Random rand, int L, int numPoints ) {
		Point2d[] res = new Point2d[numPoints];
		if( L == 0 || numPoints == 0 )
			return res;
		double x, y; // the coordinate of a new point
		double exp, mant; // exponent and mantissa
		double mantScale = Math.pow( 2.0, L )-1.0; // random mantissa scale
		int signMant = 0; // random mantissa sign

		for( int i = 0; i < numPoints; i++ ) {
			signMant = rand.nextDouble() < 0.5 ? -1 : 1;
			mant = signMant*(int)(rand.nextDouble()*mantScale);
			exp = -(int)(rand.nextDouble()*L);
			x = mant*Math.pow( 2.0, exp );
			signMant = rand.nextDouble() < 0.5 ? -1 : 1;
			mant = signMant*(int)(rand.nextDouble()*mantScale);
			exp = -(int)(rand.nextDouble()*L);
			y = mant*Math.pow( 2.0, exp );
			res[i] = new Point2d( ApfloatUtils.ValueOf( x ), ApfloatUtils.ValueOf( y ) );
		}
		return res;
	}
}
